package com.kcwx.system.service.impl;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import javax.annotation.PostConstruct;

import cn.hutool.core.util.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.kcwx.common.constant.UserConstants;
import com.kcwx.common.core.domain.entity.SysDictData;
import com.kcwx.common.core.domain.entity.SysDictType;
import com.kcwx.common.core.redis.RedisCache;
import com.kcwx.common.exception.ServiceException;
import com.kcwx.common.utils.DictUtils;
import com.kcwx.common.utils.StringUtils;

import com.kcwx.system.mapper.SysDictDataMapper;
import com.kcwx.system.mapper.SysDictTypeMapper;
import com.kcwx.system.service.ISysDictTypeService;

import com.kcwx.shareddomain.system.query.SysDictDataQuery;
import com.kcwx.shareddomain.system.query.SysDictTypeQuery;

/**
 * 字典 业务层处理
 * 
 */
@Service
public class SysDictTypeServiceImpl implements ISysDictTypeService {
	@Autowired
	private SysDictTypeMapper dictTypeMapper;

	@Autowired
	private SysDictDataMapper dictDataMapper;

	@Autowired
	private RedisCache redisCache;

	/**
	 * 项目启动时，初始化字典到缓存
	 */
	@PostConstruct
	public void init() {
		// System.out.println("项目启动初始化字典");
		// loadingDictCache();
	}

	/**
	 * 根据条件分页查询字典类型
	 * 
	 * @param dictType 字典类型信息
	 * @return 字典类型集合信息
	 */
	@Override
	public List<SysDictType> selectDictTypeList(SysDictTypeQuery dictType) {
		return dictTypeMapper.selectDictTypeList(dictType);
	}

	/**
	 * 根据所有字典类型
	 * 
	 * @return 字典类型集合信息
	 */
	@Override
	public List<SysDictType> selectDictTypeAll() {
		return dictTypeMapper.selectDictTypeAll();
	}

	/**
	 * 根据字典类型查询字典数据
	 * 
	 * @param dictType 字典类型
	 * @return 字典数据集合信息
	 */
	@Override
	public List<SysDictData> selectDictDataByType(String dictType) {
		List<SysDictData> dictDatas = DictUtils.getDictCache(dictType);
		if (StringUtils.isNotEmpty(dictDatas)) {
			return dictDatas;
		}
		dictDatas = dictDataMapper.selectDictDataByType(dictType);
		if (StringUtils.isNotEmpty(dictDatas)) {
			DictUtils.setDictCache(dictType, dictDatas);
			return dictDatas;
		}
		return null;
	}

	/**
	 * 根据字典类型查询字典数据
	 * 
	 * @param dictType 字典类型
	 * @return 字典数据集合信息
	 */
	@Override
	public List<SysDictData> selectKeyValueByType(String dictType) {
		String key = "dict:" + dictType;
		List<SysDictData> list = redisCache.getCacheObject(key);
		if (list == null || list.size() == 0) {
			list = dictDataMapper.selectKeyValueByType(dictType);
			redisCache.setCacheObject(key, list, 24, TimeUnit.HOURS);
		}
		return list;
	}

	/**
	 * 根据字典类型ID查询信息
	 * 
	 * @param dictId 字典类型ID
	 * @return 字典类型
	 */
	@Override
	public SysDictType selectDictTypeById(Long dictId) {
		return dictTypeMapper.selectDictTypeById(dictId);
	}

	/**
	 * 根据字典类型查询信息
	 * 
	 * @param dictType 字典类型
	 * @return 字典类型
	 */
	@Override
	public SysDictType selectDictTypeByType(String dictType) {
		return dictTypeMapper.selectDictTypeByType(dictType);
	}

	/**
	 * 删除字典类型信息
	 *
	 * @param dictId 需要删除的字典ID
	 * @param delBy 删除人
	 */
	@Override
	public int deleteDictTypeById(Long dictId,String delBy) {
		//根据字典类型id集合查询字典类型数据
		SysDictType dictType=dictTypeMapper.selectDictTypeById(dictId);
		if(dictType!=null){
			String strDictType=dictType.getDictType();
			//根据字典类型集合查询字典数据
			List<SysDictData> dictDataList=dictDataMapper.selectDictDataByType(strDictType);
			if(!dictDataList.isEmpty()){
				throw new ServiceException(String.format("%1$s已分配,不能删除",dictType.getDictName()));
			}
			//执行批量删除操作
			int rowsAffect= dictTypeMapper.deleteDictTypeById(dictId,delBy);
			if(rowsAffect>0){
				DictUtils.removeDictCache(strDictType);
				redisCache.deleteObject("dict:" + strDictType);
				DictUtils.removeDictCache(strDictType);
			}
			return rowsAffect;
		}
		else {
			return 1;
		}
	}
	/**
	 * 批量删除字典类型信息
	 * 
	 * @param dictIds 需要删除的字典ID
	 * @param delBy 删除人
	 */
	@Override
	public int deleteDictTypeByIds(Long[] dictIds,String delBy) {
		//根据字典类型id集合查询字典类型数据
		List<SysDictType> dictTypeList=dictTypeMapper.selectByIds(dictIds);
		if(!dictTypeList.isEmpty()){
			List<String> strDictTypes=dictTypeList.stream().map(SysDictType::getDictType).collect(Collectors.toList());
			//根据字典类型集合查询字典数据
			List<SysDictData> dictDataList=dictDataMapper.selectDictByTypes(strDictTypes.toArray(new String[0]));
			List<String> dictNames=new ArrayList<>();
			for (SysDictData dictData : dictDataList) {
			  Optional<SysDictType> singleData= dictTypeList.stream().filter(dictType->dictType.getDictType().equals(dictData.getDictType())).findFirst();
			  singleData.ifPresent(dictType->{ dictNames.add(dictType.getDictName());});
			}
			if(!dictNames.isEmpty()){
				String strDictNames= String.join(",", dictNames);
				throw new ServiceException(String.format("%1$s已分配,不能删除",strDictNames));
			}
			//执行批量删除操作
			int rowsAffect= dictTypeMapper.deleteDictTypeByIds(dictIds,delBy);
			if(rowsAffect>0){
				for(SysDictType dictType:dictTypeList){
					String dictTypeStr=dictType.getDictType();
					DictUtils.removeDictCache(dictTypeStr);
					redisCache.deleteObject("dict:" + dictTypeStr);
					DictUtils.removeDictCache(dictTypeStr);
				}
			}
			return rowsAffect;
		}
		else {
			return 1;
		}
	}

	/**
	 * 加载字典缓存数据
	 */
	@Override
	public void loadingDictCache() {
		SysDictDataQuery dictData = new SysDictDataQuery();
		dictData.setStatus(1);
		Map<String, List<SysDictData>> dictDataMap = dictDataMapper.selectDictDataList(dictData).stream()
				.collect(Collectors.groupingBy(SysDictData::getDictType));
		for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
			DictUtils.setDictCache(entry.getKey(), new ArrayList<>(entry.getValue()));
		}
	}

	/**
	 * 清空字典缓存数据
	 */
	@Override
	public void clearDictCache() {
		DictUtils.clearDictCache();
	}

	/**
	 * 重置字典缓存数据
	 */
	@Override
	public void resetDictCache() {
		clearDictCache();
		loadingDictCache();
	}

	/**
	 * 新增保存字典类型信息
	 * 
	 * @param dict 字典类型信息
	 * @return 结果
	 */
	@Override
	public int insertDictType(SysDictType dict) {
		int row = dictTypeMapper.insertDictType(dict);
		if (row > 0) {
			DictUtils.setDictCache(dict.getDictType(), null);
		}
		return row;
	}

	/**
	 * 修改保存字典类型信息
	 * 
	 * @param dict 字典类型信息
	 * @return 结果
	 */
	@Override
	@Transactional
	public int updateDictType(SysDictType dict) {
		SysDictType oldDict = dictTypeMapper.selectDictTypeById(dict.getId());
		dictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
		int row = dictTypeMapper.updateDictType(dict);
		if (row > 0) {
			DictUtils.removeDictCache(oldDict.getDictType());
			List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dict.getDictType());
			DictUtils.setDictCache(dict.getDictType(), dictDatas);
			List<SysDictData> list = redisCache.getCacheObject("dict:" + oldDict.getDictType());
			if (ObjectUtil.isNotEmpty(list)) {
				redisCache.deleteObject("dict:" + oldDict.getDictType());
				list = dictDataMapper.selectKeyValueByType(dict.getDictType());
				redisCache.setCacheObject("dict:" + dict.getDictType(), list, 24, TimeUnit.HOURS);
			}
		}
		return row;
	}

	/**
	 * 校验字典类型称是否唯一
	 * 
	 * @param dict 字典类型
	 * @return 结果
	 */
	@Override
	public String checkDictTypeUnique(SysDictType dict) {
		Long dictId = StringUtils.isNull(dict.getId()) ? -1L : dict.getId();
		SysDictType dictType = dictTypeMapper.checkDictTypeUnique(dict.getDictType());
		if (StringUtils.isNotNull(dictType) && dictType.getId().longValue() != dictId.longValue()) {
			return UserConstants.NOT_UNIQUE;
		}
		return UserConstants.UNIQUE;
	}
}
